package com.jie.eduservice.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jie.commonutils.PageUtils;
import com.jie.eduservice.entity.vo.front.CourseWebVO;
import com.jie.eduservice.entity.EduCourse;
import com.jie.eduservice.entity.EduCourseDescription;
import com.jie.eduservice.entity.vo.CourseInfoVO;
import com.jie.eduservice.entity.vo.CoursePublishVO;
import com.jie.eduservice.entity.vo.CourseQueryVO;
import com.jie.eduservice.entity.vo.front.CourseFrontVO;
import com.jie.eduservice.mapper.EduCourseDescriptionMapper;
import com.jie.eduservice.mapper.EduCourseMapper;
import com.jie.eduservice.service.EduChapterService;
import com.jie.eduservice.service.EduCourseService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jie.eduservice.service.EduVideoService;
import com.jie.servicebase.exception.GuLiException;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.Map;

/**
 * <p>
 * 课程 服务实现类
 * </p>
 *
 * @author xzj
 * @since 2020-10-09
 */
@Transactional(readOnly = true)
@Service
public class EduCourseServiceImpl extends ServiceImpl<EduCourseMapper, EduCourse> implements EduCourseService {

    // 课程描述mapper
    private final EduCourseDescriptionMapper courseDescriptionMapper;
    // 小节service(需要用到video的逻辑, 因此注入service而不是mapper)
    private final EduVideoService eduVideoService;
    // 章节service(需要用到chapter的逻辑, 因此注入service而不是mapper)
    private final EduChapterService chapterService;

    @Autowired
    public EduCourseServiceImpl(
            EduCourseDescriptionMapper courseDescriptionMapper,
            EduVideoService eduVideoService,
            EduChapterService chapterService
    ) {
        this.courseDescriptionMapper = courseDescriptionMapper;
        this.eduVideoService = eduVideoService;
        this.chapterService = chapterService;
    }

    // 添加课程信息的方法(感觉有许多需要改进的地方)
    @Transactional(  // 使用后read-only默认为false了
            // 如果当前没有事务, 就新建一个事务, 如果已经存在一个事务中, 加入到这个事务中。这是最常见的选择。
            propagation = Propagation.REQUIRED,
            rollbackFor = Exception.class
    )
    @Override
    public String saveCourseInfo(CourseInfoVO courseInfoVO) {

        // 1.向课程表添加课程的基本信息
        // 把CourseInfoVO对象转换成EduCourse对象
        EduCourse eduCourse = new EduCourse();
        BeanUtils.copyProperties(courseInfoVO, eduCourse);
        int insert = baseMapper.insert(eduCourse);
        if (insert == 0) {
            // 添加失败
            throw new GuLiException(20001, "添加课程信息失败");
        }

//        if (insert == 1) {
//            // 这段代码测试事务是否添加成功
//            throw new GuLiException(20001, "添加课程信息失败");
//        }

        // 获取添加后的课程id
        String cid = eduCourse.getId();

        // 2.向课程简介表中添加课程简介
        EduCourseDescription courseDescription = new EduCourseDescription();
        courseDescription.setId(cid);
        courseDescription.setDescription(courseInfoVO.getDescription());
        courseDescriptionMapper.insert(courseDescription);

        return cid;
    }

    @Override
    public CourseInfoVO getCourseInfo(String courseId) {

        // 1.查询课程表
        EduCourse eduCourse = baseMapper.selectById(courseId);

        // 2.查询描述表
        EduCourseDescription courseDescription = courseDescriptionMapper.selectById(courseId);

        // 3.封装CourseInfoVo对象
        CourseInfoVO courseInfoVO = new CourseInfoVO();
        BeanUtils.copyProperties(eduCourse, courseInfoVO);
        courseInfoVO.setDescription(courseDescription.getDescription());

        return courseInfoVO;
    }

    @Transactional(  // 使用后read-only默认为false了
            // 如果当前没有事务, 就新建一个事务, 如果已经存在一个事务中, 加入到这个事务中。这是最常见的选择。
            propagation = Propagation.REQUIRED,
            rollbackFor = Exception.class
    )
    @Override
    public void updateCourseInfo(CourseInfoVO courseInfoVO) {

        // 0.将VO对象转换为entity对象
        EduCourse eduCourse = new EduCourse();
        BeanUtils.copyProperties(courseInfoVO, eduCourse);

        // 1.修改课程表
        int update = baseMapper.updateById(eduCourse);
        if (update == 0) {
            throw new GuLiException(20001, "修改课程信息失败");
        }

        // 2.修改描述表
        EduCourseDescription description = new EduCourseDescription();
        description.setId(courseInfoVO.getId());
        description.setDescription(courseInfoVO.getDescription());
        courseDescriptionMapper.updateById(description);

    }

    @Override
    public CoursePublishVO getPublishCourseInfo(String id) {
        return baseMapper.getPublishCourseInfo(id);
    }

    @Override
    public Page<EduCourse> pageCourseCondition(Long current, Long limit, CourseQueryVO courseQueryVO) {
        Page<EduCourse> coursePage = new Page<>(current, limit);
        // 构建查询条件
        QueryWrapper<EduCourse> wrapper = new QueryWrapper<>();

        // 判断查询对象是否为空
        if (courseQueryVO == null) {
            // 感觉这一行有些没意义...
            baseMapper.selectPage(coursePage, null);  // 无条件
            return coursePage;
        }

        // 多条件组合查询
        // 判断条件值是否为空, 不为空则拼接条件(动态sql)
        String title = courseQueryVO.getTitle();
        String status = courseQueryVO.getStatus();
        if (!StringUtils.isEmpty(title)) {
            // 构建条件
            wrapper.like("title", title);
        }
        if (!StringUtils.isEmpty(status)) {
            wrapper.like("status", status);
        }

        // 排序查询DESC
        wrapper.orderByDesc("gmt_create");

        // 调用方法实现条件查询分页
        baseMapper.selectPage(coursePage, wrapper);
        return coursePage;
    }

    @Transactional(  // 使用后read-only默认为false了
            // 如果当前没有事务, 就新建一个事务, 如果已经存在一个事务中, 加入到这个事务中。这是最常见的选择。
            propagation = Propagation.REQUIRED,
            rollbackFor = Exception.class
    )
    @Override
    public void removeCourse(String courseId) {
        // 1.根据课程id删除小节
        eduVideoService.removeVideoByCourseId(courseId);

        // 2.根据课程id删除章节
        chapterService.removeChapterByCourseId(courseId);

        // 3.根据课程id删除描述
        courseDescriptionMapper.deleteById(courseId);

        // 4.根据课程id删除课程本身
        int result = baseMapper.deleteById(courseId);

        if (result == 0) {
            throw new GuLiException(20001, "删除失败");
        }
    }

    @Override
    public Map<String, Object> getCourseFrontList(Long page, Long limit, CourseFrontVO courseFrontVO) {
        Page<EduCourse> coursePage = new Page<>(page, limit);
        QueryWrapper<EduCourse> wrapper = new QueryWrapper<>();

        // 拼接条件
        if (!StringUtils.isEmpty(courseFrontVO.getSubjectParentId())) {  // 判断一级分类
            wrapper.eq("subject_parent_id", courseFrontVO.getSubjectParentId());
        }
        if (!StringUtils.isEmpty(courseFrontVO.getSubjectId())) {  // 判断二级分类
            wrapper.eq("subject_id", courseFrontVO.getSubjectId());
        }
        if (!StringUtils.isEmpty(courseFrontVO.getBuyCountSort())) {  // 关注度
            wrapper.orderByDesc("buy_count");
        }
        if (!StringUtils.isEmpty(courseFrontVO.getGmtCreateSort())) {  // 最新
            wrapper.orderByDesc("gmt_create");
        }
        if (!StringUtils.isEmpty(courseFrontVO.getPriceSort())) {  // 价格
            wrapper.orderByDesc("price");
        }

        baseMapper.selectPage(coursePage, wrapper);

        // 将查询到的数据放到map集合中并返回
        return PageUtils.pageToMap(coursePage);
    }

    @Override
    public CourseWebVO getBaseCourseInfo(String courseId) {
        return baseMapper.getBaseCourseInfo(courseId);
    }

}
